﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using PinCity.Models.Base;
using System.Web.Security;

namespace PinCity.Models.Accounts
{
    /// <summary>
    /// Basic class, that represents a persisted user.
    /// </summary>
    public class User : Entity
    {
        /// <summary>
        /// Stores a membership provider name, that is used to create MembershipUser objects.
        /// </summary>
        private static readonly string _membershipProviderName = Membership.Provider.Name;

        /// <summary>
        /// Gets or sets user login. Needed for authentication, authorization and display.
        /// </summary>
        public virtual string Login { get; set; }

        /// <summary>
        /// Gets or sets user password. Needed for authentication and authorization.
        /// </summary>
        public virtual string Password { get; set; }

        /// <summary>
        /// Gets or sets user e-mail. Used for communication with user and password recovery.
        /// </summary>
        public virtual string Email { get; set; }

        /// <summary>
        /// Assigned role. TODO: Tie this with custom RoleProvider.
        /// </summary>
        public virtual Role Role { get; set; }

        /// <summary>
        /// Gets or sets user creation date.
        /// </summary>
        public virtual DateTime CreationDate { get; set; }

        /// <summary>
        /// Gets or sets user last login date.
        /// </summary>
        public virtual DateTime LastLoginDate { get; set; }

        /// <summary>
        /// Gets or sets user last activity date.
        /// </summary>
        public virtual DateTime LastActivityDate { get; set; }

        /// <summary>
        /// Create a user entity and assign values to it.
        /// </summary>
        /// <param name="login">Sets the Login property.</param>
        /// <param name="password">Sets the Password property.</param>
        /// <param name="email">Sets the Email property.</param>
        /// <param name="creationDate">Sets the CreationDate property.</param>
        /// <param name="lastLoginDate">Sets the LastLoginDate property.</param>
        /// <param name="lasActivityDate">Sets the LastActivityDate property.</param>
        public User(string login, string password, string email, DateTime creationDate, DateTime lastLoginDate, DateTime lasActivityDate)
        {
            this.Login = login;
            this.Password = password;
            this.Email = email;
            this.CreationDate = creationDate;
            this.LastLoginDate = lastLoginDate;
            this.LastActivityDate = lasActivityDate;
        }

        /// <summary>
        /// Create user entity and assign default values to it.
        /// </summary>
        public User() : this("UNDEFINED_USERNAME", "UNDEFINED_PASSWORD", "UNDEFINED_EMAIL", DateTime.MinValue, DateTime.MinValue, DateTime.MinValue)
        {

        }
        /// <summary>
        /// Implicit cast to MembershipUser class operator.
        /// </summary>
        /// <param name="user">A User entity, that needs to be cast.</param>
        /// <returns>A MembershipUser object.</returns>
        public static implicit operator MembershipUser(User user)
        {
            return new MembershipUser(
                User._membershipProviderName, // Set MembershipProvider name
                user.Login, // Set username
                user.ID, // Set provider key
                user.Email, // Set email
                "", // No secret question
                "", // No answer either
                true, // Active user
                false, // Non locked-out one
                user.CreationDate,
                user.LastLoginDate,
                user.LastActivityDate,
                DateTime.MinValue, // Set last password change date 
                DateTime.MinValue // Set last lock-out date
                );
        }

        public static implicit operator User(MembershipUser user)
        {
            return new User(
                    user.UserName,
                    user.GetPassword(),
                    user.Email,
                    user.CreationDate,
                    user.LastLoginDate,
                    user.LastActivityDate
                );
        }
    }

}